package com.example.mq.mqServer.center;

import com.example.mq.mqServer.core.Binding;
import com.example.mq.mqServer.core.MSGQueue;
import com.example.mq.mqServer.core.exchange.Exchange;
import com.example.mq.mqServer.core.message.Message;
import com.example.mq.mqServer.dao.DataBaseManager;
import com.example.mq.mqServer.dao.MessageFileManager;
import com.example.mq.mqServer.exception.MqException;
import com.example.mq.mqServer.util.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;


import java.io.File;
import java.util.LinkedList;
import java.util.List;

/**
 * @BelongsProject: 0.mq
 * @BelongsPackage: com.example.mq.mqServer.dao
 * @Author : 游在海里的鱼
 * @CreateTime : 2023-12-15  15:12
 * @Version : 1.0
 * @ClassName   : 磁盘数据管理中心
 * @Description : 管理整个项目的数据持久化,包括交换机,队列,绑定和信息
 */

@Slf4j
@Repository
public class DiskDataCenter {
    //数据库数据管理者
    private DataBaseManager dataBaseManager = new DataBaseManager();
    //消息文件管理者
    private MessageFileManager messageFileManager = new MessageFileManager();

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 对象初始化
     * @Describe: TODO
     * @modifier: [public] [实例方法]
    **/
    @Transactional
    public void init()  {
        dataBaseManager.init();
        messageFileManager.init();
        log.info("[init] [磁盘数据中心]初始化成功");
    }



    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 清空所有持久化数据
     * @Describe: TODO
     * @modifier: [public] [实例方法]
    **/
    public boolean deleteDataBase() {
        File directory = new File("./data");
        if (FileUtils.deleteDirectory(directory)) {
            log.info("[deleteDataBase] 删除所有持久化数据成功,包括SQLite数据库和消息文件");
            return true;
        } else {
            new MqException("[DiskDataCenter] [deleteDataBase] [数据库meta.db]或[所有消息]删除失败").printStackTrace();
            return false;
        }
    }


    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 操控交换机
     * @Describe: 增,删,查所有,查单个
     * @modifier: [public] [实例方法]
    **/
    public void insertExchange(Exchange exchange){
        dataBaseManager.insertExchange(exchange);
        log.debug("[insertExchange] [交换机:"+exchange.getName()+"]通过[DataBaseManager对象]插入成功");
    }
    public void deleteExchange(String exchangeName) {
        dataBaseManager.deleteExchange(exchangeName);
        log.debug("[deleteExchange] [交换机:"+exchangeName+"]通过[DataBaseManager对象]删除成功");
    }
    public List<Exchange> selectAllExchange(){
        List<Exchange> ret = dataBaseManager.selectAllExchange();
        log.debug("[selectAllExchange] [所有交换机]通过[DataBaseManager对象]查询成功");
        return ret;
    }
    public Exchange selectOneOfName(String exchangeName){
        Exchange ret = dataBaseManager.selectOneExchange(exchangeName);
        log.debug("[selectOneOfName] [交换机:"+exchangeName+"]通过[DataBaseManager对象]查询成功");
        return ret;
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 操控绑定
     * @Describe: 增,删,查所有,查单个
     * @modifier: [public] [实例方法]
    **/
    public void insertBinding(Binding binding){
        dataBaseManager.insertBinding(binding);
        log.debug("[insertBinding] [队列:"+binding.getQueueName()+"]绑定[交换机:"
                +binding.getExchangeName()+"]通过[DataBaseManager对象]");
    }
    public void deleteBinding(Binding binding) {
        dataBaseManager.deleteBinding(binding);
        log.debug("[deleteBinding] [队列:"+binding.getQueueName()+"]解绑[交换机:"
                +binding.getExchangeName()+"]通过[DataBaseManager对象]");
    }
    public List<Binding> selectAllBinding(){
        List<Binding> ret = dataBaseManager.selectAllBinding();
        log.debug("[selectAllBinding] [所有绑定]通过[DataBaseManager对象]查询成功");
        return ret;
    }
    public Binding selectOneBinding(Binding binding){
        Binding ret = dataBaseManager.selectOneBinding(binding);
        log.debug("[selectOneBinding] [队列:"+binding.getQueueName()+"]和[交换机:"
                +binding.getExchangeName()+"]的绑定通过[DataBaseManager对象]查询成功");
        return ret;
    }
    

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 操控队列
     * @Describe: 增,删,查所有
     * @modifier: [public] [实例方法]
    **/
    @Transactional
    public void insertQueue(MSGQueue queue)  {
        dataBaseManager.insertQueue(queue);
        messageFileManager.createQueue(queue.getName());
        log.debug("[insertQueue] [队列:"+queue.getName()+"]通过[DataBaseManager对象]插入成功");
    }
    @Transactional
    public void deleteQueue(String queueName)  {
        dataBaseManager.deleteQueue(queueName);
        messageFileManager.deleteQueue(queueName);
        log.debug("[deleteQueue] [队列:"+queueName+"]通过[DataBaseManager对象]删除成功");
    }
    public List<MSGQueue> selectAllQueue(){
        List<MSGQueue> ret = dataBaseManager.selectAllQueue();
        log.debug("[selectAllQueue] [所有队列]通过[DataBaseManager对象]查询成功");
        return ret;
    }


    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 操控消息
     * @Describe: 增,删,查所有(每次增删都有垃圾回收的检测)
     * @modifier: [public] [实例方法]
    **/
    @Transactional
    public boolean insertMessage(MSGQueue queue, Message message) {
        boolean ret = messageFileManager.insertMessage(queue,message);
        if(messageFileManager.garbageCollection(queue)){
            log.debug("[垃圾回收] [队列:"+queue.getName()+"]进行[垃圾回收]通过[DataBaseManager对象]");
        }
        log.debug("[insertMessage] [消息"+message.getId()+"]添加进[队列:"+queue.getName()+"]通过[DataBaseManager对象]");
        return ret;
    }
    @Transactional
    public boolean deleteMessage(MSGQueue queue,Message message) {
        boolean ret = messageFileManager.deleteMessage(queue,message);
        if(messageFileManager.garbageCollection(queue)){
            log.debug("[垃圾回收] [队列:"+queue.getName()+"]进行[垃圾回收]通过[DataBaseManager对象]");
        }
        log.debug("[deleteMessage] [消息"+message.getId()+"]删除从[队列:"+queue.getName()+"]通过[DataBaseManager对象]");
        return ret;
    }
    public LinkedList<Message> selectAllMessage(String queueName){
        LinkedList<Message> ret = messageFileManager.selectAllMessage(queueName);
        log.debug("[selectAllMessage] [队列:"+queueName+"] [所有消息]通过[DataBaseManager对象]查询成功");
        return ret;
    }

}
